﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThematicClustering.Utils;
using System.Drawing;
using System.Drawing.Imaging;

namespace ThematicClustering.Algorithm
{
    public static class AppAlgorithms
    {
        // Pontosság:               97.5%   95%
        const double ChiThreshold = 9.348;//7.8147;

        /// <summary>
        /// Khí négyzet próba a kép minden pixeljére.
        /// khínégyzet = (x-nű)transzponált * covmátrix inverze * (x-nű)
        /// </summary>
        /// <param name="layers">Vizsgált kép</param>
        /// <param name="nu">Várható érték vektor</param>
        /// <param name="covMatrix">Kovarianciamátrix</param>
        /// <returns>Eredmény kép</returns>
        public static ImageLayers ChiSquareProbation(ImageLayers layers, 
                                                     SquareMatrix nu, 
                                                     SquareMatrix covMatrix)
        {
            ImageLayers result = new ImageLayers(layers.LayerCount, layers.Width, layers.Height);

            SquareMatrix Inverz = covMatrix.Inverse3x3();
            for (int j = 0; j < layers.Height; j++)
            {
                for (int i = 0; i < layers.Width; i++)
                {
                    //x-nű
                    double[] tmp = new double[layers.LayerCount];
                    for (int k = 0; k < layers.LayerCount; k++)
                    {
                            tmp[k] = layers.Layers[k, i, j] - nu[k, 0];
                    }
                    double Result = 0; ;
                    //matrix szorzas
                    for (int k = 0; k < layers.LayerCount; k++)
                    {
                        for (int l = 0; l < layers.LayerCount; l++)
                        {
                            Result += tmp[l] * Inverz[l, k] * tmp[k];
                        }
                    }
                    if (0 < Result && Result < ChiThreshold)
                        result.SetRGBVector(i, j, new byte[] { 255, 255, 255 });
                    else
                        result.SetRGBVector(i, j, new byte[] { 0, 0, 0 });
                }
            }

            return result;
        }

        /// <summary>
        /// A konzolos indítási mód
        /// </summary>
        /// <param name="input1">Első bementi kép.</param>
        /// <param name="input2">Második bemeneti kép.</param>
        /// <param name="output1">Kimeneti kép.</param>
        public static void RunInConsole(string input1, string input2, string output)
        {
            Console.Write("working ");
            Bitmap origpic, refpic, resultpic;
            Console.Write(".");
            origpic = new Bitmap(input1);
            ImageLayers Layers = new ImageLayers(origpic);
            Console.Write(".");
            refpic = new Bitmap(input2);
            ImageLayers Pattern = new ImageLayers(refpic);
            Pattern.MaskedStats(Layers);
            Console.Write(".");
            ImageLayers Result = ChiSquareProbation(Layers, Pattern.Nu, Pattern.Covariance);
            Console.Write(".");
            resultpic = Result.CreateImage();
            Console.WriteLine(".");
            resultpic.Save(output, ImageFormat.Tiff);
            Console.Write("done"); 
        }
    }
}
